/**********************************************************************
项目名称/Project          : 天气时钟
程序名称/Program name     : weather_now
团队/Team                : 
作者/Author              : 
日期/Date（YYYYMMDD）     : 2022/3/3
程序目的/Purpose          : 
通过心知天气(www.seniverse.com)免费服务获取实时天气信息。
-----------------------------------------------------------------------
其它说明 / Other Description
心知天气API文档说明: https://www.seniverse.com/docs
天气功能需要使用心知天气的API,在程序中填写自己的产品密钥。
************************************************************************/
//#include <Arduino.h>
#include <ArduinoJson.h>
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <ESP8266_Seniverse.h>         
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>  
#include "SSD1306Wire.h"    //0.96寸用这个
//#include "OLEDDisplayUi.h"
#include <stdlib.h>
#include <time.h>
#include "WeatherStationFonts.h"
#include "Display.h"

const char* ssid = "TEST";  //连接WiFi名称
const char* password = "12345678";  //wifi密码

const char* host = "api.seniverse.com";
const int httpPort = 80;

//心知天气HTTP请求所需信息,填写产品秘钥。
String reqUserKey = "xxxxxxxxxxxxxxxxx";  //秘钥
String reqLocation = "Guangzhou";       //城市
String reqUnit = "c";         //摄氏/华氏

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 8*3600;//这里采用UTC计时，中国为东八区，就是 7*60*60
const int   daylightOffset_sec = 0;//同上


const String WeatherCode[]={"Sunny","Clear","Fair","Fari","Cloudy","PartlyCloudy","PartlyCloudy",
"MostlyCloudy","MostlyCloudy","Overcast","Shower","Thundershower","ThundershowerWithHail",
"LighRain","ModerateRain","HeavyRain","Storm","HeavyStorm","SevereStorm","IceRain","Sleet",
"SnowFlurry","LightSnow","ModerateSnow","HeavySnow","Snowstorm","Dust","Sand","Duststorm","Sandstorm",
"Foggy","Haze","Windy","Blustery","Hurricane","TropicalStorm","Tornado","Cold","Hot"};

#define  KeyPin   3   //定义按键引脚IO3和RX引脚公用

String weather;
int tempe;
CurrentWeatherData c_weather;   //当前天气结构体
unsigned long preTime;
int WeatherUpdateTime = 60000;


WeatherNow weatherNow;                     // 建立WeatherNow对象用于获取心知天气信息
Forecast forecast;                         // 建立Forecast对象用于获取心知天气信息

void setup() {
  Serial.begin(9600);
  Serial.println("");
  pinMode(KeyPin,INPUT);
  //设置中断触发程序
 // attachInterrupt(digitalPinToInterrupt(KeyPin),ChangeScreen, CHANGE);
   // 屏幕初始化
  display.init();
  display.clear();
  display.display();
  display.flipScreenVertically(); //屏幕翻转
  display.clear(); 
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 10,"WeatherClock");
  display.display();
  
//连接WiFi
  connectWiFi();
//获取网络时间
configTime(gmtOffset_sec, daylightOffset_sec,"ntp.ntsc.ac.cn", "ntp1.aliyun.com" ,ntpServer);
 // 配置心知天气请求信息
  weatherNow.config(reqUserKey, reqLocation, reqUnit);
  forecast.config(reqUserKey, reqLocation, reqUnit);

  // OTA设置并启动
  ArduinoOTA.setHostname("ESP8266");
  ArduinoOTA.setPassword("12345678");
  ArduinoOTA.begin();
  
  Serial.println("OTA ready");
}

void loop() {
  
   ArduinoOTA.handle();
 // unsigned long  curTime = millis();
  
  //WeatherUpdate(curTime);  
  //if(digitalRead(KeyPin) == LOW)
  //{
  //  delay(200);
    if(digitalRead(KeyPin) == LOW)
    {
      getweather();
    }
  //  delay(200);
  //}
  displaytime();
  delay(1000); 

}

//
////中断服务函数
//void ChangeScreen()
//{
//  
//}
//

void connectWiFi()
{

  Serial.print("Connecting to ");
  display.clear(); 
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 10,"Connecting WiFi...");
  display.display();
  WiFiManager wifiManager;
  wifiManager.autoConnect("ESP01WIFI");


  Serial.println("");
  Serial.println("Connection established!");
  Serial.print("IP address:   ");
  Serial.println(WiFi.localIP());
}



void getweather()
{
  if(weatherNow.update() && forecast.update()){  // 更新天气信息
    Serial.println(F("======Weahter Info======"));
    Serial.print("Server Response: ");
    Serial.println(weatherNow.getServerCode()); // 获取服务器响应码
    Serial.print(F("Weather Now: "));
    Serial.print(weatherNow.getWeatherText());  // 获取当前天气（字符串格式）
    Serial.print(F(" "));
    Serial.println(weatherNow.getWeatherCode());// 获取当前天气（整数格式）
    Serial.print(F("Temperature: "));
    Serial.println(weatherNow.getDegree());     // 获取当前温度数值
    Serial.print(F("Last Update: "));
    Serial.println(weatherNow.getLastUpdate()); // 获取服务器更新天气信息时间
    Serial.println(F("========================"));  

    c_weather.weather_text = weatherNow.getWeatherText();
    c_weather.weather_code = weatherNow.getWeatherCode();
    c_weather.degree = weatherNow.getDegree();
    c_weather.lastupdate = weatherNow.getLastUpdate();
    c_weather.max_temperature = forecast.getHigh(0);
    c_weather.min_temperature = forecast.getLow(0);
    
    display.clear(); 
    display.setFont(ArialMT_Plain_24);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    String temp =  String(c_weather.degree) + "°C" ;
    display.drawString(80,6,temp);

    display.setFont(ArialMT_Plain_10);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(64, 50, String(c_weather.min_temperature) + "°C | " + String(c_weather.max_temperature) + "°C");
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(64,36,c_weather.weather_text);
    
    display.setFont(Meteocons_Regular_36);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    String code = getMeteoconIcon(c_weather.weather_code);
    display.drawString(25, 0,code);
    display.display();
    delay(3000);
  
       
  } else {    // 更新失败
    Serial.println("Update Fail...");   
    Serial.print("Server Response: ");          // 输出服务器响应状态码供用户查找问题
    Serial.println(weatherNow.getServerCode()); // 心知天气服务器错误代码说明可通过以下网址获取
  } 
}


void WeatherUpdate(unsigned long ct)
{
  if(ct - preTime >= WeatherUpdateTime)
  {
    getweather();
    preTime = ct;
  }
  else if(ct - preTime <= 0)
  {
    preTime = ct;
  }
}
